package com.sky.business.sys.util;

import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class AuthorizeCodeUtil {
    public static final String NUHD_FLAG = "142184";

    public static final DecimalFormat twoDecimalFormat = new DecimalFormat("00");

    public static final DecimalFormat fourDecimalFormat = new DecimalFormat("0000");

    private static final SecureRandom SECURE_RANDOM = new SecureRandom();

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");

    private static final int BASE = 20007656;

    /**
     * 获取校验码
     *
     * @param str 授权码前20位
     * @return 校验码
     */
    public static String getCheckCode(String str) {
        long sum = BASE;
        for (int i = 0; i < str.length(); i++) {
            int value = str.charAt(i) - '0';
            int k = value * (20 - i);
            sum += k;
        }
        long result = sum % 10000;
        return twoDecimalFormat.format((int) result);
    }


    public static String buildAuthorizeCode(Date date, int productTypeCode, int productIndex) {
        if (productTypeCode < 0) {
            throw new IllegalArgumentException("productTypeCode<0");
        }
        if (productTypeCode > 99) {
            throw new IllegalArgumentException("productTypeCode>99");
        }
        if (productIndex < 0) {
            throw new IllegalArgumentException("productIndex<0");
        }
        if (productIndex > 9999) {
            throw new IllegalArgumentException("productIndex>9999");
        }
        String dateStr = sdf.format(date);
        String productTypeCodeStr = twoDecimalFormat.format(productTypeCode);
        String productIndexStr = fourDecimalFormat.format(productIndex);
        String randStr = twoDecimalFormat.format(((int) (SECURE_RANDOM.nextDouble() * 1000)) % 100);
        StringBuilder result = new StringBuilder();
        result.append(NUHD_FLAG);
        result.append(dateStr);
        result.append(productTypeCodeStr);
        result.append(productIndexStr);
        result.append(randStr);
        String checkCode = getCheckCode(result.toString());
        result.append(checkCode);
        return result.toString();
    }

    public static boolean verify(String code) {
        if (code.length() != 24) {
            return false;
        }
        for (int i = 0; i < code.length(); i++) {
            if (code.charAt(i) < '0' || code.charAt(i) > '9') {
                return false;
            }
        }
        if (!code.startsWith(NUHD_FLAG)) {
            return false;
        }
        String dateStr = code.substring(6, 12);
        try {
            sdf.parse(dateStr);
        } catch (ParseException e) {
            return false;
        }
        String base = code.substring(0, 20);
        String checkCode = getCheckCode(base);
        if (!code.endsWith(checkCode)) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        Date now = new Date();
        String code = buildAuthorizeCode(now, 1, 1);
        System.out.println(code);
        System.out.println(verify("142184240923010001008229"));
    }
}
